class IUP_FORMATTING
-- The format tag element is an element with some known attributes that will be 
-- interpreted when the tag is updated in the native system.
--
-- The formatting depends on the existing text, so if VALUE attribute is set, 
-- all formatting is lost. You must set it again for the new text.
--
-- If the FONT attribute of the IupText is set then it will affect the format 
-- of all characters in the text.
--
-- The default values can not be dynamically changed.

inherit
	IUP_USER
		rename
			user as formatting
		select
			clear_attributes
		end
	IUP_WIDGET_TEXT_SELECTION

create {ANY}
	formatting

feature {ANY}

	-- General Format Tag Attributes
	set_bulk (state: BOOLEAN)
		-- Flag that means this tag is composed by several tags as its children. 
		-- Used to optimize format tag modifications. Default: False.
		do
			iup_open.set_attribute(Current, "BULK", boolean_to_yesno(state))
		end

	set_clean_out (state: BOOLEAN)
		-- When BULK=True is used to clear all the formatting at start. 
		-- Default: False.
		do
			iup_open.set_attribute(Current, "CLEANOUT", boolean_to_yesno(state))
		end

	set_multiline_selection (lin1, col1, lin2, col2: INTEGER)
		-- Selection interval in characters. The first position, lin or col, is 
		-- "1". Where lin1, col1, lin2 and col2 are integer numbers corresponding 
		-- to the selection's interval. col2 correspond to the character after 
		-- the last selected character.
		-- In Windows, when changing the selection the caret position is also 
		-- changed.
		-- See the Notes above if using UTF-8 strings in GTK. 
		local
			str: STRING
		do
			str := lin1.out
			str.append_string(",")
			str.append_string(col1.out)
	      str.append_string(":")
 	      str.append_string(lin2.out)
			str.append_string(",")
			str.append_string(col2.out)
	
			iup_open.set_attribute(Current, "SELECTION", str)
		end

	get_multiline_selection: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		-- "lin1,col1,lin2,col2" where lin1, col1, lin2 and col2 are integer 
		-- numbers corresponding to the selection's interval. col2 correspond to 
		-- the character after the last selected character.
		local
			str: STRING
			i, c: INTEGER
			pos1, pos2: STRING
			tup1, tup2: TUPLE[INTEGER, INTEGER]
			tup: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		do
			str := iup_open.get_attribute(Current, "SELECTION")

			if str.has(':') then
				i := str.index_of(':', 1)
				c := str.count
				
				if not i.is_equal(1) then
					pos1 := str.substring(1, i - 1)
				else
					pos1 := "0,0"
				end
				
				if not i.is_equal(c) then
					pos2 := str.substring(i + 1, c)
				else
					pos2 := "0,0"
				end

				tup1 := components_of_position(pos1)
				tup2 := components_of_position(pos2)

				tup := [tup1.integer_32_item(1), tup1.integer_32_item(2), tup2.integer_32_item(1), tup2.integer_32_item(2)]
				Result := tup
			else
				io.put_string("Unable to get the components %N")
				Result := [0, 0, 0, 0]
			end			
		end

	set_units (value: STRING)
		-- [Windows Only]: By default all distance units are integers in pixels, 
		-- but in Windows you can also specify integer units in TWIPs (one twip 
		-- is 1/1440 of an inch). Can be TWIP or PIXELS. Default: PIXELS.
		require
			are_valid_units(value)
		do
			iup_open.set_attribute(Current, "UNITS", value)
		end

	-- Paragraph Format Tag Attributes

	set_alignment (value: STRING)
		-- Can be JUSTIFY, RIGHT, CENTER and LEFT. Default: LEFT.
		require
			is_valid_alignment(value)
		do
			iup_open.set_attribute(Current, "ALIGNMENT", value)
		end

	set_indent (value: INTEGER)
		-- Paragraph indentation, the distance between the margin and the 
		-- paragraph. In Windows the right indentation, and the indentation of 
		-- the second and subsequent lines (relative to the indentation of the 
		-- first line) can be independently set using the INDENTRIGHT and 
		-- INDENTOFFSET attributes, but only when INDENT is set.
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "INDENT", value.out)
		end

	set_indent_right (value: INTEGER)
		-- [Windows Only] The right indentation.
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "INDENTRIGHT", value.out)
		end

	set_indent_offset (value: INTEGER)
		-- [Windows Only] The indentation of the second and subsequent lines 
		-- (relative to the indentation of the first line).
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "INDENTOFFSET", value.out)
		end

	set_line_spacing (value: INTEGER)
		-- The distance between lines of the same paragraph.
		do
			iup_open.set_attribute(Current, "LINESPACING", value.out)
		end

	set_single_line_spacing
		-- [Windows Only] Set single distance between lines of the same 
		-- paragraph.	
		do
			iup_open.set_attribute(Current, "LINESPACING", "SINGLE")
		end

	set_onehalf_line_spacing
		-- [Windows Only] Set onehalf distance between lines of the same 
		-- paragraph.	
		do
			iup_open.set_attribute(Current, "LINESPACING", "ONEHALF")
		end

	set_double_line_spacing
		-- [Windows Only] Set double distance between lines of the same 
		-- paragraph.	
		do
			iup_open.set_attribute(Current, "LINESPACING", "DOUBLE")
		end

	set_numbering (value: STRING)
		-- [Windows Only]: Can be BULLET (bullet symbol), ARABIC (arabic numbers 
		-- - 1,2,3...), LCLETTER (lowercase letters - a,b,c...), UCLETTER 
		-- (uppercase letters - A,B,C...), LCROMAN (lowercase Roman numerals - 
		-- i,ii,iii...), UCROMAN (uppercase Roman numerals - I,II,III...) and 
		-- NONE. Default: NONE.
		require
			is_valid_numbering(value)
		do
			iup_open.set_attribute(Current, "NUMBERING", value)
		end

	set_numbering_style (value: STRING)
		-- [Windows Only]: Can be RIGHTPARENTESES "a)", PARENTESES "(a)", PERIOD 
		-- "a.", NONUMBER (it will skip the numbering or bullet for the item) and 
		-- NONE "". Default: NONE.
		require
			is_valid_numbering_style(value)
		do
			iup_open.set_attribute(Current, "NUMBERINGSTYLE", value)
		end

	set_numbering_tab (value: INTEGER)
		-- [Windows Only]: Minimum distance from a paragraph numbering or bullet 
		-- to the paragraph text.
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "NUMBERINGTAB", value.out)
		end

	set_space_after (value: INTEGER)
		-- Distance left empty above the paragraph.
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "SPACEAFTER", value.out)
		end

	set_space_before (value: INTEGER)
		-- Distance left empty below the paragraph.
		require
			value >= 0
		do
			iup_open.set_attribute(Current, "SPACEBEFORE", value.out)
		end

	set_tabs_array (value: STRING)
		-- A sequence of tab positions and alignment up to 32 tabs. It uses the 
		-- format:"pos align pos align pos align...". Position is the distance 
		-- relative to the left margin and alignment can be LEFT, CENTER, RIGHT 
		-- and DECIMAL. In GTK only LEFT is currently supported. When DECIMAL 
		-- alignment is used, the text is aligned according to a decimal point or 
		-- period in the text, it is normally used to align numbers.
		do
			iup_open.set_attribute(Current, "TABSARRAY", value)
		end

	-- Character Format Tag Attributes

	set_rgb_background_color (red: INTEGER; green: INTEGER; blue: INTEGER)
		-- Set the background color of the text.
		do
			iup_open.set_attribute(Current, "BGCOLOR",
			                       rgb_to_string(red, green, blue))
		end

	set_disabled (state: BOOLEAN)
		-- [Windows Only]: Can be YES or NO. Default NO. Set the visual 
		-- appearance to disabled.
		do
			iup_open.set_attribute(Current, "DISABLED", boolean_to_yesno(state))
		end

	set_rgb_foreground_color (red: INTEGER; green: INTEGER; blue: INTEGER)
		-- Set the foreground color of the text.
		do
			iup_open.set_attribute(Current, "FGCOLOR",
			                       rgb_to_string(red, green, blue))
		end

	set_font_scale (value: REAL_32)
		-- A size scale relative to the selected or current size. Values greatter 
		-- than 1 will increase the font. Values smaller than 1 will shirnk the 
		-- font. Default: 1.0. 
		require
			value >= ((0).to_real)
		do
			iup_open.set_attribute(Current, "FONTSCALE", value.out)
		end

	set_string_font_scale (value: STRING)
		-- The following values are accpeted: "XX-SMALL" (0.58), "X-SMALL" 
		-- (0.64), "SMALL" (0.83), "MEDIUM" (1.0), "LARGE" (1.2), "X-LARGE" 
		-- (1.44), "XX-LARGE" (1.73).
		require
			is_valid_font_scale(value)
		do
			iup_open.set_attribute(Current, "FONTSCALE", value)
		end

	set_fontface (fontface: STRING)
		-- Te face name of the font.
		do
			iup_open.set_attribute(Current, "FONTFACE", fontface)
		end

	set_fontsize (fontsize: INTEGER)
		-- The size of the font in pixels or points. Pixel size uses negative 
		-- values.	
		do
			iup_open.set_attribute(Current, "FONTSIZE", fontsize.out)
		end

	set_italic (state: BOOLEAN)
		-- Default False.
		do
			iup_open.set_attribute(Current, "ITALIC", boolean_to_yesno(state))
		end

	set_language (value: STRING)
		-- [GTK Only]: A text with a description of the text language. The same 
		-- value can be used in the "SYSTEMLANGUAGE" global attribute.
		do
			iup_open.set_attribute(Current, "LANGUAGE", value)
		end

	set_rise (value: INTEGER)
		-- The distance, positive or negative from the base line.
		do
			iup_open.set_attribute(Current, "RISE", value.out)
		end

	set_superscript
		do
			iup_open.set_attribute(Current, "RISE", "SUPERSCRIPT")
		end

	set_subscript
		do
			iup_open.set_attribute(Current, "RISE", "SUBSCRIPT")
		end

	set_smallcaps (state: BOOLEAN)
		-- [GTK Only]: Default: False. (Does not work always, depends on the font)
		do
			iup_open.set_attribute(Current, "SMALLCAPS", boolean_to_yesno(state))
		end

	set_protected (state: BOOLEAN)
		-- Default: False. When set to True the selected text can NOT be edited.
		do
			iup_open.set_attribute(Current, "PROTECTED", boolean_to_yesno(state))
		end

	set_stretch (value: STRING)
		-- [GTK Only]: Can be EXTRA_CONDENSED, CONDENSED, SEMI_CONDENSED, NORMAL, 
		-- SEMI_EXPANDED, EXPANDED and EXTRA_EXPANDED. Default NORMAL. (Does not 
		-- work always, depends on the font)
		require
			is_valid_stretch(value)
		do
			iup_open.set_attribute(Current, "STRETCH", value)
		end

	set_strikeout (state: BOOLEAN)
		-- Default: False.
		do
			iup_open.set_attribute(Current, "STRIKEOUT", boolean_to_yesno(state))
		end

	set_underline (value: STRING)
		-- Can be SINGLE, DOUBLE, DOTTED or NONE. Default NONE. DOTTED is 
		-- supported only in Windows.
		require
			is_valid_underline(value)
		do
			iup_open.set_attribute(Current, "UNDERLINE", value)
		end

	set_weight (value: STRING)
		-- Can be EXTRALIGHT, LIGHT, NORMAL, SEMIBOLD, BOLD, EXTRABOLD and 
		-- HEAVY. Default: NORMAL.
		require
			is_valid_weight(value)
		do
			iup_open.set_attribute(Current, "WEIGHT", value)
		end

	-- Validations

	is_valid_alignment (value: STRING): BOOLEAN
		do
			if value.is_equal("JUSTIFY") or
				value.is_equal("RIGHT") or
				value.is_equal("CENTER") or
				value.is_equal("LEFT") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_numbering (value: STRING): BOOLEAN
		do
			if value.is_equal("BULLET") or
				value.is_equal("ARABIC") or
				value.is_equal("LCLETTER") or
				value.is_equal("UCLETTER") or
				value.is_equal("LCROMAN") or
				value.is_equal("UCROMAN") or
				value.is_equal("NONE") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_numbering_style (value: STRING): BOOLEAN
		do
			if value.is_equal("RIGHTPARENTESES") or
				value.is_equal("PARENTESES") or
				value.is_equal("PERIOD") or
				value.is_equal("NONUMBER") or
				value.is_equal("NONE") then
				Result := True
			else
				Result := False
			end
		end

	are_valid_units (value: STRING): BOOLEAN
		do
			if value.is_equal("TWIP") or
				value.is_equal("PIXELS") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_font_scale (value: STRING): BOOLEAN
		do
			if value.is_equal("XX-SMALL") or
				value.is_equal("X-SMALL") or
				value.is_equal("SMALL") or
				value.is_equal("MEDIUM") or
				value.is_equal("LARGE") or
				value.is_equal("X-LARGE") or
				value.is_equal("XX-LARGE") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_stretch (value: STRING): BOOLEAN
		do
			if value.is_equal("EXTRA_CONDENSED") or
				value.is_equal("CONDENSED") or
				value.is_equal("SEMI_CONDENSED") or
				value.is_equal("NORMAL") or
				value.is_equal("SEMI_EXPANDED") or
				value.is_equal("EXPANDED") or
				value.is_equal("EXTRA_EXPANDED") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_underline (value: STRING): BOOLEAN
		do
			if value.is_equal("SINGLE") or
				value.is_equal("DOUBLE") or
				value.is_equal("DOTTED") or
				value.is_equal("NONE") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_weight (value: STRING): BOOLEAN
		do
			if value.is_equal("EXTRALIGHT") or
				value.is_equal("LIGHT") or
				value.is_equal("NORMAL") or
				value.is_equal("SEMIBOLD") or
				value.is_equal("BOLD") or
				value.is_equal("EXTRABOLD") or
				value.is_equal("HEAVY") then
				Result := True
			else
				Result := False
			end
		end

end

-- The MIT License (MIT)

-- Copyright (c) 2016, 2019 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.

